package com.northpool.operator.transfer;

import com.northpool.operator.annotation.InputParam;
import com.northpool.operator.annotation.InputParams;
import com.northpool.operator.annotation.OperatorInfo;
import com.northpool.operator.annotation.ParamEnum;
import com.northpool.operator.annotation.ParamEnums;
import com.northpool.operator.common.algorithm.OperatorTestBuild;
import com.northpool.operator.common.algorithm.TestParamBuilder;
import com.northpool.operator.common.database.DatabaseUtils;
import com.northpool.operator.common.stpclient.StpClientOperatorBase;
import com.northpool.operator.param.ParamTool;
import com.northpool.operator.type.TypeEnum;
import com.northpool.resources.Constants;
import com.northpool.resources.datasource.IDataSource;
import com.northpool.resources.datasource.ogr.ShapeDataSource;
import com.northpool.resources.datatable.ITable;
import com.northpool.stpclient.bean.BaseResponse;
import com.northpool.stpclient.bean.datatransfer.TableCopyBuildPlan;
import com.northpool.stpclient.bean.datatransfer.TbaleCopyModeEnum;
import com.northpool.stpclient.modules.geoprocess.datatransfer.IDataTransferOperator;


@OperatorInfo(
        ref = "Pg2ShpOperator",
        name = "Postgres转Shape",
        description = "",
        enums = {
                @ParamEnums(ref = "mode", value = {
                        @ParamEnum(ref = "REPLACE", name = "删除重建"),
                        @ParamEnum(ref = "MERGE", name = "合并"),
                        @ParamEnum(ref = "APPENDER", name = "追加"),
                })
        }
)
public class Pg2ShpOperator extends StpClientOperatorBase {

    @InputParams({
            @InputParam(ref = "dataSourceId", name = "数据源ID", desc = "数据源ID", type = TypeEnum.DATASOURCE, required = true),
            @InputParam(ref = "tableName", name = "数据表名称", desc = "数据表名称，如: public.table", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "targetDir", name = "目标文件夹", desc = "目标文件夹, 应为共享文件夹", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "shpName", name = "shp文件名", desc = "shp文件名", type = TypeEnum.STRING, required = true),
            @InputParam(ref = "mode", name = "传输类型", desc = "传输类型", type = TypeEnum.STRING, value = "REPLACE", enumRef = "mode"),
    })
    public Pg2ShpOperator() {
    }

    public static void main(String[] args) throws Exception {
        OperatorTestBuild.execute(Pg2ShpOperator.class, TestParamBuilder.aBuilder()
                .param("dataSourceId", "8ae4b0ab96af528f0196f798e2b5051f")
                .param("tableName", "public.dms_system_region")
                .param("targetDir", "D:\\data\\GisData\\dms_system_region\\dms_system_region.shp")
                .param("shpName", "dms_system_region")
                .param("mode", "REPLACE")
                .build()
        );
    }

    @Override
    public void execute(ParamTool params) throws Exception {
        String dataSourceId = params.getStr("dataSourceId");
        String tableName = params.getStr("tableName");
        String targetFilePath = params.getStr("targetDir");
        String shpName = params.getStr("shpName");
        String mode = params.getStr("mode");

        IDataTransferOperator transferOperator = this.client.dataTransferOperator();

        String dataSourceJson = DatabaseUtils.getDataSourceJson(dataSourceId);
        IDataSource dataSource = IDataSource.fromJSON(dataSourceJson);
        if (dataSource == null || !dataSource.getDataSourceType().equals(Constants.DATA_SOURCE_TYPE.postgreSQL)) {
            throw new RuntimeException(dataSourceId + ": 数据源未找到或类型不是 postgreSQL");
        }
        ITable table = dataSource.getTable(tableName);
        Integer srid = table.spatialInfo().getSrid();

        ShapeDataSource shapeDataSource = new ShapeDataSource(targetFilePath);

        TableCopyBuildPlan plan = TableCopyBuildPlan.TableCopyParamsBuilder.create()
                .addSrid(srid)
                // 设置来源数据源
                .addOriginDatasource(dataSource)
                // 设置来源表
                .addOriginTableName(tableName)
                // 设置目标数据源
                .addTargetDatasource(shapeDataSource)
                // 设置目标表名
                .addTargetTableName(shpName)
                .addMode(TbaleCopyModeEnum.valueOf(mode))
                .build();
        BaseResponse response = transferOperator.startTableCopy(plan);
        String requestId = response.getRequestId();
        transferOperator.onStart(requestId, () -> {
            log("开始数据传输");
        });
        transferOperator.onError(requestId, () -> {
            error(transferOperator.log(requestId));
            this.failedExit();
        });
        transferOperator.onSuccess(requestId, this::successExit);
        this.waiting(24);
    }
}
